package data;

import java.util.HashSet;
import java.util.Set;

import exceptions.IdentifierException;
import exceptions.DataException;

/**
 * Immutable Game
 * @author poet
 */
public class Game {
	private Player player1;
	private Player player2;
	private int player1score;
	private int player2score;
	/**
	 * Each game must have a unique ID.
	 */
	private int gameID;
	private Environment environment;
	/**
	 * String environment
	 * @throws IdentifierException 
	 */
	public Game(Player player1, Player player2, int player1score,int player2score,
			int gameID, String environment) throws DataException, IdentifierException {
		 this(player1,player2,player1score,player2score,gameID,Environment.valueOf(environment));
	}
	/**
	 * enum environment
	 * @throws IdentifierException 
	 */
	public Game(Player player1, Player player2, int player1score,int player2score,
			int gameID, Environment environment) throws DataException, IdentifierException {
		addIdentifier(gameID);
		if (player1==null || player2==null)
			throw new DataException("Win players",Player.class.getName());
		this.player1 = player1;
		this.player2 = player2;
		this.player1score = player1score;
		this.player2score = player2score;
		this.gameID = gameID;
		if (environment==null)
			throw new DataException("Environemnt missing",Player.class.getName());
		this.environment = environment;
	}
	
	//Unique identifier enforcer
	private static Set<Integer> identifiers;
	private static void addIdentifier(int identifier) throws IdentifierException{
		if (Game.identifiers==null)
			Game.identifiers = new HashSet<Integer>();
		if (identifiers.contains(identifier))
			throw new IdentifierException(identifier,Game.class.getName());
		identifiers.add(identifier);
	}
	/**
	 * Enum immutable so no need for defensive copying
	 */
	public Environment getEnvironment() {
		return environment;
	}
	/**
	 * primitive immutable so no need for defensive copying.
	 */
	public int getGameID() {
		return gameID;
	}
	
	/**
	 * Player immutable so no need for defensive copying.
	 */
	public Player getPlayer1() {
		return player1;
	}
	/**
	 * Player immutable so no need for defensive copying.
	 */
	public Player getPlayer2() {
		return player2;
	}
	/**
	 * primitive immutable so no need for defensive copying.
	 */
	public int getPlayer1score() {
		return player1score;
	}
	/**
	 * primitive immutable so no need for defensive copying.
	 */
	public int getPlayer2score() {
		return player2score;
	}
	@Override
	public int hashCode(){
		return gameID;
	}
	@Override
	public String toString(){
		return "Game #" + gameID + " " + player1.getPlayerName() + " " + player1score + " " + player2.getPlayerName() + " " + player2score + " " + environment;
	}
	@Override
	public boolean equals(Object o){
		if (!(o instanceof Game))
			return false;
		if (this.gameID != ((Game)o).gameID)
			return false;
		return true;
	}
}
